using System;
using System.IO;
using FireStarter.CodeGeneration;
using FireStarterModeller.BO;
using NUnit.Framework;

namespace FireStarter.Test.CodeGeneration
{
    [TestFixture] 
    public class TestWinProjectGenerator : TestProjectGeneratorBase
    {

        private static WinProjectGenerator CreateWinProjectReadyToGenerate()
        {
            WinProjectGenerator projectGenerator = new WinProjectGenerator();
            CreateSolutionGenerator(projectGenerator);
            projectGenerator.ProjectPath = GetRootedPath(Path.Combine(TEST_PROJECTS_FOLDER, GetRandomString()));
            projectGenerator.ProjectName = "TestProject.Win";
            projectGenerator.ModelSolution.BOProjectName = GetRandomString();
            projectGenerator.ModelSolution.UIProjectName = GetRandomString();
            projectGenerator.ModelSolution.UIWinProjectName = GetRandomString();
            return projectGenerator;
        }

        protected override IProjectGenerator CreateProjectReadyToGenerate()
        {
            return CreateWinProjectReadyToGenerate();
        }

        protected override IProjectGenerator CreateProjectGenerator()
        {
            return new WinProjectGenerator();
        }

        private void AssertProjectGeneratedCorrectly(WinProjectGenerator winProjectGenerator, ProjectFileManager uiProjectFileManager)
        {
            string libFolderName = winProjectGenerator.SolutionGenerator.HabaneroReferencePath;
            libFolderName = Utilities.GetRelativePath(libFolderName, winProjectGenerator.ProjectPath);
            string projectFileName = winProjectGenerator.ProjectFileName;
            Assert.IsTrue(Directory.Exists(winProjectGenerator.ProjectPath));
            Assert.IsTrue(File.Exists(projectFileName));
            ProjectFileManager projectFileManager = new ProjectFileManager(projectFileName, CodeTemplateEnum.CSharpVisualStudio2005);
            Assert.AreEqual(OutputType.WinExe, projectFileManager.OutputType);
            string projectFileContents = File.ReadAllText(projectFileName);
            StringAssert.Contains("<Compile Include=\"UIManagerWin.cs\" />", projectFileContents);
            StringAssert.Contains("<Compile Include=\"Program.cs\" />", projectFileContents);
            StringAssert.Contains("<None Include=\"App.config\" />", projectFileContents);
            StringAssert.Contains(@"<Compile Include=""Properties\AssemblyInfo.cs"" />", projectFileContents);
            AssertHasProjectReference(projectFileContents, winProjectGenerator, uiProjectFileManager);
            AssertHasReference(projectFileContents, string.Format(@"{0}\Habanero.Base.dll", libFolderName));
            AssertHasReference(projectFileContents, string.Format(@"{0}\Habanero.BO.dll", libFolderName));
            AssertHasReference(projectFileContents, string.Format(@"{0}\Habanero.Faces.Base.dll", libFolderName));
            AssertHasReference(projectFileContents, string.Format(@"{0}\Habanero.Faces.Win.dll", libFolderName));
            AssertHasNotReference(projectFileContents, string.Format(@"{0}\Habanero.Util.dll", libFolderName));
            AssertHasReference(projectFileContents, string.Format(@"{0}\log4net.dll", libFolderName));
            AssertHasSystemReference(projectFileContents, string.Format(@"System.Windows.Forms"));
        }

        [Test]
        public void TestCreateWinProjectGenerator()
        {
            //---------------Set up test pack-------------------

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            IProjectGenerator winProjectGenerator = CreateProjectGenerator();
            //---------------Test Result -----------------------
            Assert.IsNotNull(winProjectGenerator);
            Assert.IsInstanceOf(typeof(WinProjectGenerator), winProjectGenerator);
        }

        //[Test]
        //public void TestUIProjectReference()
        //{
        //    //---------------Set up test pack-------------------
        //    string uiProjectName = GetRandomString();
        //    WinProjectGenerator winProjectGenerator = new WinProjectGenerator();
        //    //---------------Assert Precondition----------------
        //    Assert.IsNull(winProjectGenerator.UIProjectFileName);
        //    //---------------Execute Test ----------------------
        //    winProjectGenerator.UIProjectFileName = uiProjectName;
        //    //---------------Test Result -----------------------
        //    Assert.AreEqual(uiProjectName, winProjectGenerator.UIProjectFileName);
        //}

        //[Test]
        //public void TestGenerate_Fails_UiProjectReferenceNotSet()
        //{
        //    //---------------Set up test pack-------------------
        //    WinProjectGenerator winProjectGenerator = CreateWinProjectReadyToGenerate();
        //    winProjectGenerator.UIProjectFileName = null;
        //    //---------------Assert Precondition----------------
        //    Assert.IsNull(winProjectGenerator.UIProjectFileName);
        //    //---------------Execute Test ----------------------
        //    Exception exception = null;
        //    try
        //    {
        //        winProjectGenerator.Generate();
        //    }
        //    catch (Exception ex)
        //    {
        //        exception = ex;
        //    }
        //    //---------------Test Result -----------------------
        //    Assert.IsNotNull(exception, "Exception Expected");
        //    Assert.IsInstanceOf(typeof(ReferenceMissingException), exception);
        //    ReferenceMissingException referenceMissingException = (ReferenceMissingException)exception;
        //    Assert.AreEqual("UI Project", referenceMissingException.ReferenceName);
        //}

        [Test]
        public void TestGenerate_Creates_ProjectFile_IfDoesNotExist()
        {
            //---------------Set up test pack-------------------
            WinProjectGenerator winProjectGenerator = CreateWinProjectReadyToGenerate();
            ProjectFileManager uiProjectFileManager = CreateRandomProjectFile(winProjectGenerator.ModelSolution.UIProjectName);
            string projectFileName = winProjectGenerator.ProjectFileName;
            //---------------Assert Precondition----------------
            Assert.IsFalse(File.Exists(projectFileName));
            //---------------Execute Test ----------------------
            winProjectGenerator.Generate();
            //---------------Test Result -----------------------
            AssertProjectGeneratedCorrectly(winProjectGenerator, uiProjectFileManager);
        }

        public abstract class TestWinProjectGenerator_GeneratedFile : TestProjectGeneratorBase_GeneratedFile
        {
            protected override IProjectGenerator CreateProjectReadyToGenerate()
            {
                return CreateWinProjectReadyToGenerate();
            }

            protected override void AssertFileGeneratedCorrectly(IProjectGenerator projectGenerator, string fileContents)
            {
                WinProjectGenerator winProjectGenerator = (WinProjectGenerator)projectGenerator;
                AssertFileGeneratedCorrectlyWin(winProjectGenerator, fileContents);
            }

            protected abstract void AssertFileGeneratedCorrectlyWin(WinProjectGenerator winProjectGenerator, string fileContents);
        }

        public class TestWinProjectGenerator_GeneratedFile_UIManagerWin : TestWinProjectGenerator_GeneratedFile
        {
            protected override string GetFileName()
            {
                return "UIManagerWin.cs";
            }

            protected override void AssertFileGeneratedCorrectlyWin(WinProjectGenerator winProjectGenerator, string fileContents)
            {
                ProjectFileManager projectFileManager = new ProjectFileManager(winProjectGenerator.ModelSolution.UIProjectName, CodeTemplateEnum.CSharpVisualStudio2005);
                TestWinProjectTemplateLoader.AssertUiManagerWinCorrect(fileContents, winProjectGenerator.ProjectName, projectFileManager.AssemblyName);
            }
        }

        public class TestWinProjectGenerator_GeneratedFile_Program : TestWinProjectGenerator_GeneratedFile
        {
            protected override string GetFileName()
            {
                return "Program.cs";
            }

            protected override void AssertFileGeneratedCorrectlyWin(WinProjectGenerator winProjectGenerator, string fileContents)
            {
                TestWinProjectTemplateLoader.AssertProgramCorrect(fileContents, winProjectGenerator.ProjectName, winProjectGenerator.ProjectName, "v1.0", winProjectGenerator.ModelSolution.BOProjectName);
            }
        }

        public class TestWinProjectGenerator_GeneratedFile_AppConfig : TestWinProjectGenerator_GeneratedFile
        {
            protected override string GetFileName()
            {
                return "App.config";
            }

            protected override bool CheckProjectHasFile(ProjectFileManager projectFileManager, string fileName)
            {
                return projectFileManager.HasFile(fileName);
            }

            protected override IProjectGenerator CreateProjectReadyToGenerate()
            {
                IProjectGenerator projectGenerator = base.CreateProjectReadyToGenerate();
                WinProjectGenerator winProjectGenerator = (WinProjectGenerator)projectGenerator;
                //DatabaseSettings databaseSettings = new DatabaseSettings();
                //winProjectGenerator.DatabaseSettings = databaseSettings;
                //databaseSettings.Vendor = GetRandomString();
                //databaseSettings.Server = GetRandomString();
                //databaseSettings.Port = GetRandomString();
                //databaseSettings.Database = GetRandomString();
                //databaseSettings.Username = GetRandomString();
                //databaseSettings.Password = GetRandomString();
                return winProjectGenerator;
            }

            protected override void AssertFileGeneratedCorrectlyWin(WinProjectGenerator winProjectGenerator, string fileContents)
            {
                //DatabaseSettings databaseSettings = winProjectGenerator.DatabaseSettings;
                //TestWinProjectTemplateLoader.AssertAppConfigCorrect(fileContents, winProjectGenerator.ProjectName,
                //    databaseSettings.Vendor, databaseSettings.Server, databaseSettings.Port,
                //    databaseSettings.Database, databaseSettings.Username, databaseSettings.Password);
                TestWinProjectTemplateLoader.AssertAppConfigCorrect(fileContents,
                                                                    winProjectGenerator.SolutionGenerator.ModelSolution.
                                                                        ApplicationName,
                                                                    "InMemory", "", "", "", "", "");
            }
        }
    }
}

